#include "stepper_motor.h"
#include "math.h"

extern TIM_HandleTypeDef htim8;


/********************************************梯形加减速***********************************************/
speedRampData g_srd1               = {STOP,CW,0,0,0,0,0};  /* 加减速变量 */
__IO uint8_t  g_motion_sta1        = 0;                    /* 是否在运动？0：停止，1：运动 */
speedRampData g_srd2               = {STOP,CW,0,0,0,0,0};  /* 加减速变量 */
__IO uint8_t  g_motion_sta2        = 0;                    /* 是否在运动？0：停止，1：运动 */
speedRampData g_srd3              = {STOP,CW,0,0,0,0,0};  /* 加减速变量 */
__IO uint8_t  g_motion_sta3        = 0;                    /* 是否在运动？0：停止，1：运动 */
speedRampData g_srd4               = {STOP,CW,0,0,0,0,0};  /* 加减速变量 */
__IO uint8_t  g_motion_sta4        = 0;                    /* 是否在运动？0：停止，1：运动 */

uint64_t g_step_position1 = 0;
uint64_t g_step_position2 = 0;
uint64_t g_step_position3 = 0;
uint64_t g_step_position4 = 0;  //绝对位置有方向 相对位置无方向

/*
 * @brief       生成梯形运动控制参数
 * @param       step：移动的步数 (正数为顺时针，负数为逆时针).
 * @param       accel  加速度,实际值为accel*0.1*rad/sec^2  放大10倍并且2个脉冲算一个完整的周期
 * @param       decel  减速度,实际值为decel*0.1*rad/sec^2
 * @param       speed  最大速度,实际值为speed*0.1*rad/sec
 * @retval      无
 */
void step1_create_t_ctrl_param(int32_t step, uint32_t accel, uint32_t decel, uint32_t speed)
{
    __IO uint16_t tim_count;        /* 达到最大速度时的步数*/
    __IO uint32_t max_s_lim;        /* 必须要开始减速的步数（如果加速没有达到最大速度）*/
    __IO uint32_t accel_lim;
    if(g_motion_sta1 != STOP)        /* 只允许步进电机在停止的时候才继续*/
        return;
    if(step < 0)                    /* 步数为负数 */
    {   
        g_srd1.dir = CCW;            /* 逆时针方向旋转 */
        ST1_DIR(CCW);
        step = -step;               /* 获取步数绝对值 */
    }
    else
    {
        g_srd1.dir = CW;             /* 顺时针方向旋转 */
        ST1_DIR(CW);
    }

    if(step == 1)                   /* 步数为1 */
    {
        g_srd1.accel_count = -1;     /* 只移动一步 */
        g_srd1.run_state = DECEL;    /* 减速状态. */
        g_srd1.step_delay = 500;    /* 默认速度 */  //即C值
    }
    else if(step != 0)              /* 如果目标运动步数不为0*/  //不为0也不为1 --- 有加速和匀速阶段
    {
        /*设置最大速度极限, 计算得到min_delay用于定时器的计数器的值 min_delay = (alpha / t)/ w*/
        g_srd1.min_delay = (int32_t)(A_T_x10 /speed); //匀速运行时的计数值 //最小的C,对应最大的v,即匀速阶段

        /* 通过计算第一个(c0) 的步进延时来设定加速度，其中accel单位为0.1rad/sec^2
         step_delay = 1/tt * sqrt(2*alpha/accel)
         step_delay = ( tfreq*0.69/10 )*10 * sqrt( (2*alpha*100000) / (accel*10) )/100 */
        
        g_srd1.step_delay = (int32_t)((T1_FREQ_148 * sqrt(A_SQ / accel))/10); /* c0 */

        max_s_lim = (uint32_t)(speed*speed / (A_x200*accel/10));/* 计算多少步之后达到最大速度的限制 max_s_lim = speed^2 / (2*alpha*accel) */

        if(max_s_lim == 0)                                      /* 如果达到最大速度小于0.5步，我们将四舍五入为0,但实际我们必须移动至少一步才能达到想要的速度 */
        {
            max_s_lim = 1;
        }
        accel_lim = (uint32_t)(step*decel/(accel+decel));       /* 这里不限制最大速度 计算多少步之后我们必须开始减速 n1 = (n1+n2)decel / (accel + decel) */

        if(accel_lim == 0)                                      /* 不足一步 按一步处理*/
        {
            accel_lim = 1;
        }
        if(accel_lim <= max_s_lim)                              /* 加速阶段到不了最大速度就得减速。。。使用限制条件我们可以计算出减速阶段步数 */
        {
            g_srd1.decel_val = accel_lim - step;                 /* 减速段的步数 */
        }
        else
        {
            g_srd1.decel_val = -(max_s_lim*accel/decel);         /* 减速段的步数 */
        }
        if(g_srd1.decel_val == 0)                                /* 不足一步 按一步处理 */
        {
            g_srd1.decel_val = -1;
        }
        g_srd1.decel_start = step + g_srd1.decel_val;             /* 计算开始减速时的步数 */
        
        
        if(g_srd1.step_delay <= g_srd1.min_delay)                 /* 如果一开始c0的速度比匀速段速度还大，就不需要进行加速运动，直接进入匀速 */
        {
            g_srd1.step_delay = g_srd1.min_delay;
            g_srd1.run_state = RUN;
        }
        else  
        {
            g_srd1.run_state = ACCEL;
        }
        g_srd1.accel_count = 0;                                  /* 复位加减速计数值 */
    }
    g_motion_sta1 = 1;                                           /* 电机为运动状态 */
    ST1_EN(EN_ON);
    tim_count=__HAL_TIM_GET_COUNTER(&htim8);
    __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_1,tim_count+g_srd1.step_delay/2);  /* 设置定时器比较值 */
    HAL_TIM_OC_Start_IT(&htim8,TIM_CHANNEL_1);                                  /* 使能定时器通道 */
}

void step2_create_t_ctrl_param(int32_t step, uint32_t accel, uint32_t decel, uint32_t speed)
{
    __IO uint16_t tim_count;        /* 达到最大速度时的步数*/
    __IO uint32_t max_s_lim;        /* 必须要开始减速的步数（如果加速没有达到最大速度）*/
    __IO uint32_t accel_lim;
    if(g_motion_sta2 != STOP)        /* 只允许步进电机在停止的时候才继续*/
        return;
    if(step < 0)                    /* 步数为负数 */
    {   
        g_srd2.dir = CCW;            /* 逆时针方向旋转 */
        ST2_DIR(CCW);
        step = -step;               /* 获取步数绝对值 */
    }
    else
    {
        g_srd2.dir = CW;             /* 顺时针方向旋转 */
        ST2_DIR(CW);
    }

    if(step == 1)                   /* 步数为1 */
    {
        g_srd2.accel_count = -1;     /* 只移动一步 */
        g_srd2.run_state = DECEL;    /* 减速状态. */
        g_srd2.step_delay = 500;    /* 默认速度 */  //即C值
    }
    else if(step != 0)              /* 如果目标运动步数不为0*/  //不为0也不为1 --- 有加速和匀速阶段
    {
        /*设置最大速度极限, 计算得到min_delay用于定时器的计数器的值 min_delay = (alpha / t)/ w*/
        g_srd2.min_delay = (int32_t)(A_T_x10 /speed); //匀速运行时的计数值 //最小的C,对应最大的v,即匀速阶段

        /* 通过计算第一个(c0) 的步进延时来设定加速度，其中accel单位为0.1rad/sec^2
         step_delay = 1/tt * sqrt(2*alpha/accel)
         step_delay = ( tfreq*0.69/10 )*10 * sqrt( (2*alpha*100000) / (accel*10) )/100 */
        
        g_srd2.step_delay = (int32_t)((T1_FREQ_148 * sqrt(A_SQ / accel))/10); /* c0 */

        max_s_lim = (uint32_t)(speed*speed / (A_x200*accel/10));/* 计算多少步之后达到最大速度的限制 max_s_lim = speed^2 / (2*alpha*accel) */

        if(max_s_lim == 0)                                      /* 如果达到最大速度小于0.5步，我们将四舍五入为0,但实际我们必须移动至少一步才能达到想要的速度 */
        {
            max_s_lim = 1;
        }
        accel_lim = (uint32_t)(step*decel/(accel+decel));       /* 这里不限制最大速度 计算多少步之后我们必须开始减速 n1 = (n1+n2)decel / (accel + decel) */

        if(accel_lim == 0)                                      /* 不足一步 按一步处理*/
        {
            accel_lim = 1;
        }
        if(accel_lim <= max_s_lim)                              /* 加速阶段到不了最大速度就得减速。。。使用限制条件我们可以计算出减速阶段步数 */
        {
            g_srd2.decel_val = accel_lim - step;                 /* 减速段的步数 */
        }
        else
        {
            g_srd2.decel_val = -(max_s_lim*accel/decel);         /* 减速段的步数 */
        }
        if(g_srd2.decel_val == 0)                                /* 不足一步 按一步处理 */
        {
            g_srd2.decel_val = -1;
        }
        g_srd2.decel_start = step + g_srd2.decel_val;             /* 计算开始减速时的步数 */
        
        
        if(g_srd2.step_delay <= g_srd2.min_delay)                 /* 如果一开始c0的速度比匀速段速度还大，就不需要进行加速运动，直接进入匀速 */
        {
            g_srd2.step_delay = g_srd2.min_delay;
            g_srd2.run_state = RUN;
        }
        else  
        {
            g_srd2.run_state = ACCEL;
        }
        g_srd2.accel_count = 0;                                  /* 复位加减速计数值 */
    }
    g_motion_sta2 = 1;                                           /* 电机为运动状态 */
    ST2_EN(EN_ON);
    tim_count=__HAL_TIM_GET_COUNTER(&htim8);
    __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_2,tim_count+g_srd2.step_delay/2);  /* 设置定时器比较值 */
    HAL_TIM_OC_Start_IT(&htim8,TIM_CHANNEL_2);                                  /* 使能定时器通道 */
}


void step3_create_t_ctrl_param(int32_t step, uint32_t accel, uint32_t decel, uint32_t speed)
{
    __IO uint16_t tim_count;        /* 达到最大速度时的步数*/
    __IO uint32_t max_s_lim;        /* 必须要开始减速的步数（如果加速没有达到最大速度）*/
    __IO uint32_t accel_lim;
    if(g_motion_sta3 != STOP)        /* 只允许步进电机在停止的时候才继续*/
        return;
    if(step < 0)                    /* 步数为负数 */
    {   
        g_srd3.dir = CCW;            /* 逆时针方向旋转 */
        ST3_DIR(CCW);
        step = -step;               /* 获取步数绝对值 */
    }
    else
    {
        g_srd3.dir = CW;             /* 顺时针方向旋转 */
        ST3_DIR(CW);
    }

    if(step == 1)                   /* 步数为1 */
    {
        g_srd3.accel_count = -1;     /* 只移动一步 */
        g_srd3.run_state = DECEL;    /* 减速状态. */
        g_srd3.step_delay = 500;    /* 默认速度 */  //即C值
    }
    else if(step != 0)              /* 如果目标运动步数不为0*/  //不为0也不为1 --- 有加速和匀速阶段
    {
        /*设置最大速度极限, 计算得到min_delay用于定时器的计数器的值 min_delay = (alpha / t)/ w*/
        g_srd3.min_delay = (int32_t)(A_T_x10 /speed); //匀速运行时的计数值 //最小的C,对应最大的v,即匀速阶段

        /* 通过计算第一个(c0) 的步进延时来设定加速度，其中accel单位为0.1rad/sec^2
         step_delay = 1/tt * sqrt(2*alpha/accel)
         step_delay = ( tfreq*0.69/10 )*10 * sqrt( (2*alpha*100000) / (accel*10) )/100 */
        
        g_srd3.step_delay = (int32_t)((T1_FREQ_148 * sqrt(A_SQ / accel))/10); /* c0 */

        max_s_lim = (uint32_t)(speed*speed / (A_x200*accel/10));/* 计算多少步之后达到最大速度的限制 max_s_lim = speed^2 / (2*alpha*accel) */

        if(max_s_lim == 0)                                      /* 如果达到最大速度小于0.5步，我们将四舍五入为0,但实际我们必须移动至少一步才能达到想要的速度 */
        {
            max_s_lim = 1;
        }
        accel_lim = (uint32_t)(step*decel/(accel+decel));       /* 这里不限制最大速度 计算多少步之后我们必须开始减速 n1 = (n1+n2)decel / (accel + decel) */

        if(accel_lim == 0)                                      /* 不足一步 按一步处理*/
        {
            accel_lim = 1;
        }
        if(accel_lim <= max_s_lim)                              /* 加速阶段到不了最大速度就得减速。。。使用限制条件我们可以计算出减速阶段步数 */
        {
            g_srd3.decel_val = accel_lim - step;                 /* 减速段的步数 */
        }
        else
        {
            g_srd3.decel_val = -(max_s_lim*accel/decel);         /* 减速段的步数 */
        }
        if(g_srd3.decel_val == 0)                                /* 不足一步 按一步处理 */
        {
            g_srd3.decel_val = -1;
        }
        g_srd3.decel_start = step + g_srd3.decel_val;             /* 计算开始减速时的步数 */
        
        
        if(g_srd3.step_delay <= g_srd3.min_delay)                 /* 如果一开始c0的速度比匀速段速度还大，就不需要进行加速运动，直接进入匀速 */
        {
            g_srd3.step_delay = g_srd3.min_delay;
            g_srd3.run_state = RUN;
        }
        else  
        {
            g_srd3.run_state = ACCEL;
        }
        g_srd3.accel_count = 0;                                  /* 复位加减速计数值 */
    }
    g_motion_sta3 = 1;                                           /* 电机为运动状态 */
    ST3_EN(EN_ON);
    tim_count=__HAL_TIM_GET_COUNTER(&htim8);
    __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_3,tim_count+g_srd3.step_delay/2);  /* 设置定时器比较值 */
    HAL_TIM_OC_Start_IT(&htim8,TIM_CHANNEL_3);                                  /* 使能定时器通道 */
}


void step4_create_t_ctrl_param(int32_t step, uint32_t accel, uint32_t decel, uint32_t speed)
{
    __IO uint16_t tim_count;        /* 达到最大速度时的步数*/
    __IO uint32_t max_s_lim;        /* 必须要开始减速的步数（如果加速没有达到最大速度）*/
    __IO uint32_t accel_lim;
    if(g_motion_sta4 != STOP)        /* 只允许步进电机在停止的时候才继续*/
        return;
    if(step < 0)                     /* 步数为负数 */
    {   
        g_srd4.dir = CCW;            /* 逆时针方向旋转 */
        ST4_DIR(CCW);
        step = -step;                /* 获取步数绝对值 */
    }
    else
    {
        g_srd4.dir = CW;             /* 顺时针方向旋转 */
        ST4_DIR(CW);
    }

    if(step == 1)                    /* 步数为1 */
    {
        g_srd4.accel_count = -1;     /* 只移动一步 */
        g_srd4.run_state = DECEL;    /* 减速状态. */
        g_srd4.step_delay = 500;     /* 默认速度 */  //即C值
    }
    else if(step != 0)              /* 如果目标运动步数不为0*/  //不为0也不为1 --- 有加速和匀速阶段
    {
        /*设置最大速度极限, 计算得到min_delay用于定时器的计数器的值 min_delay = (alpha / t)/ w*/
        g_srd4.min_delay = (int32_t)(A_T_x10 /speed); //匀速运行时的计数值 //最小的C,对应最大的v,即匀速阶段

        /* 通过计算第一个(c0) 的步进延时来设定加速度，其中accel单位为0.1rad/sec^2
         step_delay = 1/tt * sqrt(2*alpha/accel)
         step_delay = ( tfreq*0.69/10 )*10 * sqrt( (2*alpha*100000) / (accel*10) )/100 */
        
        g_srd4.step_delay = (int32_t)((T1_FREQ_148 * sqrt(A_SQ / accel))/10); /* c0 */

        max_s_lim = (uint32_t)(speed*speed / (A_x200*accel/10));/* 计算多少步之后达到最大速度的限制 max_s_lim = speed^2 / (2*alpha*accel) */

        if(max_s_lim == 0)                                      /* 如果达到最大速度小于0.5步，我们将四舍五入为0,但实际我们必须移动至少一步才能达到想要的速度 */
        {
            max_s_lim = 1;
        }
        accel_lim = (uint32_t)(step*decel/(accel+decel));       /* 这里不限制最大速度 计算多少步之后我们必须开始减速 n1 = (n1+n2)decel / (accel + decel) */

        if(accel_lim == 0)                                      /* 不足一步 按一步处理*/
        {
            accel_lim = 1;
        }
        if(accel_lim <= max_s_lim)                              /* 加速阶段到不了最大速度就得减速。。。使用限制条件我们可以计算出减速阶段步数 */
        {
            g_srd4.decel_val = accel_lim - step;                 /* 减速段的步数 */
        }
        else
        {
            g_srd4.decel_val = -(max_s_lim*accel/decel);         /* 减速段的步数 */
        }
        if(g_srd4.decel_val == 0)                                /* 不足一步 按一步处理 */
        {
            g_srd4.decel_val = -1;
        }
        g_srd4.decel_start = step + g_srd4.decel_val;             /* 计算开始减速时的步数 */
        
        
        if(g_srd4.step_delay <= g_srd4.min_delay)                 /* 如果一开始c0的速度比匀速段速度还大，就不需要进行加速运动，直接进入匀速 */
        {
            g_srd4.step_delay = g_srd4.min_delay;
            g_srd4.run_state = RUN;
        }
        else  
        {
            g_srd4.run_state = ACCEL;
        }
        g_srd4.accel_count = 0;                                  /* 复位加减速计数值 */
    }
    g_motion_sta4 = 1;                                           /* 电机为运动状态 */
    ST4_EN(EN_ON);
    tim_count=__HAL_TIM_GET_COUNTER(&htim8);
    __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_4,tim_count+g_srd4.step_delay/2);  /* 设置定时器比较值 */
    HAL_TIM_OC_Start_IT(&htim8,TIM_CHANNEL_4);                                  /* 使能定时器通道 */
}

/**
  * @brief  定时器比较中断
  * @param  htim：定时器句柄指针
  * @note   无
  * @retval 无
  */
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance==TIM8)
    {
       __IO uint32_t tim_count = 0;
       __IO uint32_t tmp = 0;
       uint16_t new_step_delay = 0;                            /* 保存新（下）一个延时周期 */
       if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
       {
            
            __IO static uint16_t last_accel_delay1 = 0;              /* 加速过程中最后一次延时（脉冲周期） */
            __IO static uint32_t step_count1 = 0;                    /* 总移动步数计数器*/
            __IO static int32_t rest1 = 0;                           /* 记录new_step_delay中的余数，提高下一步计算的精度 */
            __IO static uint8_t i1 = 0;                              /* 定时器使用翻转模式，需要进入两次中断才输出一个完整脉冲 */

            tim_count = __HAL_TIM_GET_COUNTER(&htim8);
            tmp = tim_count + g_srd1.step_delay/2;               /* 整个C值里边是需要翻转两次的所以需要除以2 */
            __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_1,tmp);

            i1++;                                                /* 定时器中断次数计数值 */
            if(i1 == 2)                                          /* 2次，说明已经输出一个完整脉冲 */
            {
                i1 = 0;                                          /* 清零定时器中断次数计数值 */
                switch(g_srd1.run_state)                         /* 加减速曲线阶段 */
                {
                case STOP:
                    step_count1 = 0;                             /* 清零步数计数器 */
                    rest1 = 0;                                   /* 清零余值 */
                    /* 关闭通道*/
                    __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_1,1);
                    HAL_TIM_OC_Stop_IT(&htim8, TIM_CHANNEL_1);
                    ST1_EN(EN_OFF);
                    g_motion_sta1 = 0;                           /* 电机为停止状态  */
                    break;

                case ACCEL:
                    step_count1++;                               /* 步数加1*/
                    g_srd1.accel_count++;                        /* 加速计数值加1*/
                    if(g_srd1.dir == CW)
                    {
                        g_step_position1++;                      /* 绝对位置加1  记录绝对位置转动多少度*/
                    }
                    else
                    {
                        g_step_position1--;                      /* 绝对位置减1*/
                    }
                    
                    new_step_delay = g_srd1.step_delay - (((2 *g_srd1.step_delay) + rest1)/(4 * g_srd1.accel_count + 1));/* 计算新(下)一步脉冲周期(时间间隔) */
                    rest1 = ((2 * g_srd1.step_delay)+rest1)%(4 * g_srd1.accel_count + 1);                                /* 计算余数，下次计算补上余数，减少误差 */
                    if(step_count1 >= g_srd1.decel_start)         /* 检查是否到了需要减速的步数 */
                    {
                        g_srd1.accel_count = g_srd1.decel_val;    /* 加速计数值为减速阶段计数值的初始值 */
                        g_srd1.run_state = DECEL;                /* 下个脉冲进入减速阶段 */
                    }
                    else if(new_step_delay <= g_srd1.min_delay)  /* 检查是否到达期望的最大速度 计数值越小速度越快，当你的速度和最大速度相等或更快就进入匀速*/
                    {
                        last_accel_delay1 = new_step_delay;      /* 保存加速过程中最后一次延时（脉冲周期）*/
                        new_step_delay = g_srd1.min_delay;       /* 使用min_delay（对应最大速度speed）*/
                        rest1 = 0;                               /* 清零余值 */
                        g_srd1.run_state = RUN;                  /* 设置为匀速运行状态 */
                    }
                    break;

                case RUN:
                    step_count1++;                               /* 步数加1 */
                    if(g_srd1.dir == CW)
                    {
                        g_step_position1++;                      /* 绝对位置加1  记录绝对位置转动多少度*/
                    }
                    else
                    {
                        g_step_position1--;                      /* 绝对位置减1*/
                    }

                    new_step_delay = g_srd1.min_delay;           /* 使用min_delay（对应最大速度speed）*/
                    if(step_count1 >= g_srd1.decel_start)         /* 需要开始减速 */
                    {
                        g_srd1.accel_count = g_srd1.decel_val;    /* 减速步数做为加速计数值 */
                        new_step_delay = last_accel_delay1;      /* 加阶段最后的延时做为减速阶段的起始延时(脉冲周期) */
                        g_srd1.run_state = DECEL;                /* 状态改变为减速 */
                    }
                    break;

                case DECEL:
                    step_count1++;                               /* 步数加1 */
                    if(g_srd1.dir == CW)
                    {
                        g_step_position1++;                      /* 绝对位置加1  记录绝对位置转动多少度*/
                    }
                    else
                    {
                        g_step_position1--;                      /* 绝对位置减1*/
                    }

                    g_srd1.accel_count++;
                    new_step_delay = g_srd1.step_delay - (((2 * g_srd1.step_delay) + rest1)/(4 * g_srd1.accel_count + 1));  /* 计算新(下)一步脉冲周期(时间间隔) */
                    rest1 = ((2 * g_srd1.step_delay)+rest1)%(4 * g_srd1.accel_count + 1);                                   /* 计算余数，下次计算补上余数，减少误差 */

                    /* 检查是否为最后一步 */
                    if(g_srd1.accel_count >= 0)                  /* 判断减速步数是否从负值加到0是的话 减速完成 */
                    {
                        g_srd1.run_state = STOP;
                    }
                    break;
                }
                g_srd1.step_delay = new_step_delay;              /* 为下个(新的)延时(脉冲周期)赋值 */
            }
       }


       if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2)
       {
            __IO static uint16_t last_accel_delay2 = 0;              /* 加速过程中最后一次延时（脉冲周期） */
            __IO static uint32_t step_count2 = 0;                    /* 总移动步数计数器*/
            __IO static int32_t rest2 = 0;                           /* 记录new_step_delay中的余数，提高下一步计算的精度 */
            __IO static uint8_t i2 = 0;                              /* 定时器使用翻转模式，需要进入两次中断才输出一个完整脉冲 */

            tim_count = __HAL_TIM_GET_COUNTER(&htim8);
            tmp = tim_count + g_srd2.step_delay/2;               /* 整个C值里边是需要翻转两次的所以需要除以2 */
            __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_2,tmp);

            i2++;                                                /* 定时器中断次数计数值 */
            if(i2 == 2)                                          /* 2次，说明已经输出一个完整脉冲 */
            {
                i2 = 0;                                          /* 清零定时器中断次数计数值 */
                switch(g_srd2.run_state)                         /* 加减速曲线阶段 */
                {
                case STOP:
                    step_count2 = 0;                             /* 清零步数计数器 */
                    rest2 = 0;                                   /* 清零余值 */
                    /* 关闭通道*/
                    __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_2,1);
                    HAL_TIM_OC_Stop_IT(&htim8, TIM_CHANNEL_2);
                    ST2_EN(EN_OFF);
                    g_motion_sta2 = 0;                           /* 电机为停止状态  */
                    break;

                case ACCEL:
                    step_count2++;                               /* 步数加1*/
                    if(g_srd2.dir == CW)
                    {
                        g_step_position2++;                      /* 绝对位置加1  记录绝对位置转动多少度*/
                    }
                    else
                    {
                        g_step_position2--;                      /* 绝对位置减1*/
                    }

                    g_srd2.accel_count++;                        /* 加速计数值加1*/
                    new_step_delay = g_srd2.step_delay - (((2 *g_srd2.step_delay) + rest2)/(4 * g_srd2.accel_count + 1));/* 计算新(下)一步脉冲周期(时间间隔) */
                    rest2 = ((2 * g_srd2.step_delay)+rest2)%(4 * g_srd2.accel_count + 1);                                /* 计算余数，下次计算补上余数，减少误差 */
                    if(step_count2 >= g_srd2.decel_start)         /* 检查是否到了需要减速的步数 */
                    {
                        g_srd2.accel_count = g_srd2.decel_val;    /* 加速计数值为减速阶段计数值的初始值 */
                        g_srd2.run_state = DECEL;                /* 下个脉冲进入减速阶段 */
                    }
                    else if(new_step_delay <= g_srd2.min_delay)  /* 检查是否到达期望的最大速度 计数值越小速度越快，当你的速度和最大速度相等或更快就进入匀速*/
                    {
                        last_accel_delay2 = new_step_delay;      /* 保存加速过程中最后一次延时（脉冲周期）*/
                        new_step_delay = g_srd2.min_delay;       /* 使用min_delay（对应最大速度speed）*/
                        rest2 = 0;                               /* 清零余值 */
                        g_srd2.run_state = RUN;                  /* 设置为匀速运行状态 */
                    }
                    break;

                case RUN:
                    step_count2++;                               /* 步数加1 */
                    if(g_srd2.dir == CW)
                    {
                        g_step_position2++;                      /* 绝对位置加1  记录绝对位置转动多少度*/
                    }
                    else
                    {
                        g_step_position2--;                      /* 绝对位置减1*/
                    }

                    new_step_delay = g_srd2.min_delay;           /* 使用min_delay（对应最大速度speed）*/
                    if(step_count2 >= g_srd2.decel_start)         /* 需要开始减速 */
                    {
                        g_srd2.accel_count = g_srd2.decel_val;    /* 减速步数做为加速计数值 */
                        new_step_delay = last_accel_delay2;      /* 加阶段最后的延时做为减速阶段的起始延时(脉冲周期) */
                        g_srd2.run_state = DECEL;                /* 状态改变为减速 */
                    }
                    break;

                case DECEL:
                    step_count2++;                               /* 步数加1 */
                    if(g_srd2.dir == CW)
                    {
                        g_step_position2++;                      /* 绝对位置加1  记录绝对位置转动多少度*/
                    }
                    else
                    {
                        g_step_position2--;                      /* 绝对位置减1*/
                    }

                    g_srd2.accel_count++;
                    new_step_delay = g_srd2.step_delay - (((2 * g_srd2.step_delay) + rest2)/(4 * g_srd2.accel_count + 1));  /* 计算新(下)一步脉冲周期(时间间隔) */
                    rest2 = ((2 * g_srd2.step_delay)+rest2)%(4 * g_srd2.accel_count + 1);                                   /* 计算余数，下次计算补上余数，减少误差 */

                    /* 检查是否为最后一步 */
                    if(g_srd2.accel_count >= 0)                  /* 判断减速步数是否从负值加到0是的话 减速完成 */
                    {
                        g_srd2.run_state = STOP;
                    }
                    break;
                }
                g_srd2.step_delay = new_step_delay;              /* 为下个(新的)延时(脉冲周期)赋值 */
            }
       }
       if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3)
       {
            __IO static uint16_t last_accel_delay3 = 0;              /* 加速过程中最后一次延时（脉冲周期） */
            __IO static uint32_t step_count3 = 0;                    /* 总移动步数计数器*/
            __IO static int32_t rest3 = 0;                           /* 记录new_step_delay中的余数，提高下一步计算的精度 */
            __IO static uint8_t i3 = 0;                              /* 定时器使用翻转模式，需要进入两次中断才输出一个完整脉冲 */

            tim_count = __HAL_TIM_GET_COUNTER(&htim8);
            tmp = tim_count + g_srd3.step_delay/2;               /* 整个C值里边是需要翻转两次的所以需要除以2 */
            __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_3,tmp);

            i3++;                                                /* 定时器中断次数计数值 */
            if(i3 == 2)                                          /* 2次，说明已经输出一个完整脉冲 */
            {
                i3 = 0;                                          /* 清零定时器中断次数计数值 */
                switch(g_srd3.run_state)                         /* 加减速曲线阶段 */
                {
                case STOP:
                    step_count3 = 0;                             /* 清零步数计数器 */
                    rest3 = 0;                                   /* 清零余值 */
                    /* 关闭通道*/
                    __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_3,1);
                    HAL_TIM_OC_Stop_IT(&htim8, TIM_CHANNEL_3);
                    ST3_EN(EN_OFF);
                    g_motion_sta3 = 0;                           /* 电机为停止状态  */
                    break;

                case ACCEL:
                    step_count3++;                               /* 步数加1*/
                    if(g_srd3.dir == CW)
                    {
                        g_step_position3++;                      /* 绝对位置加1  记录绝对位置转动多少度*/
                    }
                    else
                    {
                        g_step_position3--;                      /* 绝对位置减1*/
                    }

                    g_srd3.accel_count++;                        /* 加速计数值加1*/
                    new_step_delay = g_srd3.step_delay - (((2 *g_srd3.step_delay) + rest3)/(4 * g_srd3.accel_count + 1));/* 计算新(下)一步脉冲周期(时间间隔) */
                    rest3 = ((2 * g_srd3.step_delay)+rest3)%(4 * g_srd3.accel_count + 1);                                /* 计算余数，下次计算补上余数，减少误差 */
                    if(step_count3 >= g_srd3.decel_start)         /* 检查是否到了需要减速的步数 */
                    {
                        g_srd3.accel_count = g_srd3.decel_val;    /* 加速计数值为减速阶段计数值的初始值 */
                        g_srd3.run_state = DECEL;                /* 下个脉冲进入减速阶段 */
                    }
                    else if(new_step_delay <= g_srd3.min_delay)  /* 检查是否到达期望的最大速度 计数值越小速度越快，当你的速度和最大速度相等或更快就进入匀速*/
                    {
                        last_accel_delay3 = new_step_delay;      /* 保存加速过程中最后一次延时（脉冲周期）*/
                        new_step_delay = g_srd3.min_delay;       /* 使用min_delay（对应最大速度speed）*/
                        rest3 = 0;                               /* 清零余值 */
                        g_srd3.run_state = RUN;                  /* 设置为匀速运行状态 */
                    }
                    break;

                case RUN:
                    step_count3++;                               /* 步数加1 */
                    if(g_srd3.dir == CW)
                    {
                        g_step_position3++;                      /* 绝对位置加1  记录绝对位置转动多少度*/
                    }
                    else
                    {
                        g_step_position3--;                      /* 绝对位置减1*/
                    }

                    new_step_delay = g_srd3.min_delay;           /* 使用min_delay（对应最大速度speed）*/
                    if(step_count3 >= g_srd3.decel_start)         /* 需要开始减速 */
                    {
                        g_srd3.accel_count = g_srd3.decel_val;    /* 减速步数做为加速计数值 */
                        new_step_delay = last_accel_delay3;      /* 加阶段最后的延时做为减速阶段的起始延时(脉冲周期) */
                        g_srd3.run_state = DECEL;                /* 状态改变为减速 */
                    }
                    break;

                case DECEL:
                    step_count3++;                               /* 步数加1 */
                    if(g_srd3.dir == CW)
                    {
                        g_step_position3++;                      /* 绝对位置加1  记录绝对位置转动多少度*/
                    }
                    else
                    {
                        g_step_position3--;                      /* 绝对位置减1*/
                    }
                    
                    g_srd3.accel_count++;
                    new_step_delay = g_srd3.step_delay - (((2 * g_srd3.step_delay) + rest3)/(4 * g_srd3.accel_count + 1));  /* 计算新(下)一步脉冲周期(时间间隔) */
                    rest3 = ((2 * g_srd3.step_delay)+rest3)%(4 * g_srd3.accel_count + 1);                                   /* 计算余数，下次计算补上余数，减少误差 */

                    /* 检查是否为最后一步 */
                    if(g_srd3.accel_count >= 0)                  /* 判断减速步数是否从负值加到0是的话 减速完成 */
                    {
                        g_srd3.run_state = STOP;
                    }
                    break;
                }
                g_srd3.step_delay = new_step_delay;              /* 为下个(新的)延时(脉冲周期)赋值 */
            }
       }
       if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4)
       {
            __IO static uint16_t last_accel_delay4 = 0;              /* 加速过程中最后一次延时（脉冲周期） */
            __IO static uint32_t step_count4 = 0;                    /* 总移动步数计数器*/
            __IO static int32_t rest4 = 0;                           /* 记录new_step_delay中的余数，提高下一步计算的精度 */
            __IO static uint8_t i4 = 0;                              /* 定时器使用翻转模式，需要进入两次中断才输出一个完整脉冲 */

            tim_count = __HAL_TIM_GET_COUNTER(&htim8);
            tmp = tim_count + g_srd4.step_delay/2;               /* 整个C值里边是需要翻转两次的所以需要除以2 */
            __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_4,tmp);

            i4++;                                                /* 定时器中断次数计数值 */
            if(i4 == 2)                                          /* 2次，说明已经输出一个完整脉冲 */
            {
                i4 = 0;                                          /* 清零定时器中断次数计数值 */
                switch(g_srd4.run_state)                         /* 加减速曲线阶段 */
                {
                case STOP:
                    step_count4 = 0;                             /* 清零步数计数器 */
                    rest4 = 0;                                   /* 清零余值 */
                    /* 关闭通道*/
                    __HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_4,1);
                    HAL_TIM_OC_Stop_IT(&htim8, TIM_CHANNEL_4);
                    ST4_EN(EN_OFF);
                    g_motion_sta4 = 0;                           /* 电机为停止状态  */
                    break;

                case ACCEL:
                    step_count4++;                               /* 步数加1*/
                    if(g_srd4.dir == CW)
                    {
                        g_step_position4++;                      /* 绝对位置加1  记录绝对位置转动多少度*/
                    }
                    else
                    {
                        g_step_position4--;                      /* 绝对位置减1*/
                    }

                    g_srd4.accel_count++;                        /* 加速计数值加1*/
                    new_step_delay = g_srd4.step_delay - (((2 *g_srd4.step_delay) + rest4)/(4 * g_srd4.accel_count + 1));/* 计算新(下)一步脉冲周期(时间间隔) */
                    rest4 = ((2 * g_srd4.step_delay)+rest4)%(4 * g_srd4.accel_count + 1);                                /* 计算余数，下次计算补上余数，减少误差 */
                    if(step_count4 >= g_srd4.decel_start)         /* 检查是否到了需要减速的步数 */
                    {
                        g_srd4.accel_count = g_srd4.decel_val;    /* 加速计数值为减速阶段计数值的初始值 */
                        g_srd4.run_state = DECEL;                /* 下个脉冲进入减速阶段 */
                    }
                    else if(new_step_delay <= g_srd4.min_delay)  /* 检查是否到达期望的最大速度 计数值越小速度越快，当你的速度和最大速度相等或更快就进入匀速*/
                    {
                        last_accel_delay4 = new_step_delay;      /* 保存加速过程中最后一次延时（脉冲周期）*/
                        new_step_delay = g_srd4.min_delay;       /* 使用min_delay（对应最大速度speed）*/
                        rest4 = 0;                               /* 清零余值 */
                        g_srd4.run_state = RUN;                  /* 设置为匀速运行状态 */
                    }
                    break;

                case RUN:
                    step_count4++;                               /* 步数加1 */
                    if(g_srd4.dir == CW)
                    {
                        g_step_position4++;                      /* 绝对位置加1  记录绝对位置转动多少度*/
                    }
                    else
                    {
                        g_step_position4--;                      /* 绝对位置减1*/
                    }
                    
                    new_step_delay = g_srd4.min_delay;           /* 使用min_delay（对应最大速度speed）*/
                    if(step_count4 >= g_srd4.decel_start)         /* 需要开始减速 */
                    {
                        g_srd4.accel_count = g_srd4.decel_val;    /* 减速步数做为加速计数值 */
                        new_step_delay = last_accel_delay4;      /* 加阶段最后的延时做为减速阶段的起始延时(脉冲周期) */
                        g_srd4.run_state = DECEL;                /* 状态改变为减速 */
                    }
                    break;

                case DECEL:
                    step_count4++;                               /* 步数加1 */
                    if(g_srd4.dir == CW)
                    {
                        g_step_position4++;                      /* 绝对位置加1  记录绝对位置转动多少度*/
                    }
                    else
                    {
                        g_step_position4--;                      /* 绝对位置减1*/
                    }

                    g_srd4.accel_count++;
                    new_step_delay = g_srd4.step_delay - (((2 * g_srd4.step_delay) + rest4)/(4 * g_srd4.accel_count + 1));  /* 计算新(下)一步脉冲周期(时间间隔) */
                    rest4 = ((2 * g_srd4.step_delay)+rest4)%(4 * g_srd4.accel_count + 1);                                   /* 计算余数，下次计算补上余数，减少误差 */

                    /* 检查是否为最后一步 */
                    if(g_srd4.accel_count >= 0)                  /* 判断减速步数是否从负值加到0是的话 减速完成 */
                    {
                        g_srd4.run_state = STOP;
                    }
                    break;
                }
                g_srd4.step_delay = new_step_delay;              /* 为下个(新的)延时(脉冲周期)赋值 */
            }
       }

        
    }
}